home *** CD-ROM | disk | FTP | other *** search
/ Aminet 52 / Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso / Aminet / dev / c / expat-dev.lha / expat-1.95.5 / xmlwf / xmlfile.c < prev    next >
C/C++ Source or Header  |  2002-09-09  |  6KB  |  242 lines

  1. /* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
  2.    See the file COPYING for copying permission.
  3. */
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <stddef.h>
  8. #include <string.h>
  9. #include <fcntl.h>
  10. #ifdef COMPILED_FROM_DSP
  11. #include "winconfig.h"
  12. #else
  13. #include "expat_config.h"
  14. #endif
  15.  
  16. #ifndef AMIGA
  17. #include "expat.h"
  18. #else
  19. #include <exec/types.h>
  20. #include <exec/memory.h>
  21. #include <expat/expat.h>
  22. #include <proto/exec.h>
  23. #include <proto/expat.h>
  24. #endif
  25.  
  26. #include "xmlfile.h"
  27. #include "xmltchar.h"
  28. #include "filemap.h"
  29.  
  30. #ifdef _MSC_VER
  31. #include <io.h>
  32. #endif
  33.  
  34. #ifdef HAVE_UNISTD_H
  35. #include <unistd.h>
  36. #endif
  37.  
  38. #ifndef O_BINARY
  39. #ifdef _O_BINARY
  40. #define O_BINARY _O_BINARY
  41. #else
  42. #define O_BINARY 0
  43. #endif
  44. #endif
  45.  
  46. #ifdef _DEBUG
  47. #define READ_SIZE 16
  48. #else
  49. #define READ_SIZE (1024*8)
  50. #endif
  51.  
  52.  
  53. typedef struct {
  54.   XML_Parser parser;
  55.   int *retPtr;
  56. } PROCESS_ARGS;
  57.  
  58. static void
  59. reportError(XML_Parser parser, const XML_Char *filename)
  60. {
  61.   int code = XML_GetErrorCode(parser);
  62.   const XML_Char *message = XML_ErrorString(code);
  63.   if (message)
  64.     ftprintf(stdout, T("%s:%d:%d: %s\n"),
  65.              filename,
  66.              XML_GetErrorLineNumber(parser),
  67.              XML_GetErrorColumnNumber(parser),
  68.              message);
  69.   else
  70.     ftprintf(stderr, T("%s: (unknown message %d)\n"), filename, code);
  71. }
  72.  
  73. static void
  74. processFile(const void *data, size_t size,
  75.             const XML_Char *filename, void *args)
  76. {
  77.   XML_Parser parser = ((PROCESS_ARGS *)args)->parser;
  78.   int *retPtr = ((PROCESS_ARGS *)args)->retPtr;
  79.   if (XML_Parse(parser, data, size, 1) == XML_STATUS_ERROR) {
  80.     reportError(parser, filename);
  81.     *retPtr = 0;
  82.   }
  83.   else
  84.     *retPtr = 1;
  85. }
  86.  
  87. #ifdef WIN32
  88.  
  89. static int
  90. isAsciiLetter(XML_Char c)
  91. {
  92.   return (T('a') <= c && c <= T('z')) || (T('A') <= c && c <= T('Z'));
  93. }
  94.  
  95. #endif /* WIN32 */
  96.  
  97. static const XML_Char *
  98. resolveSystemId(const XML_Char *base, const XML_Char *systemId,
  99.                 XML_Char **toFree)
  100. {
  101.   XML_Char *s;
  102.   *toFree = 0;
  103.   if (!base
  104.       || *systemId == T('/')
  105. #ifdef WIN32
  106.       || *systemId == T('\\')
  107.       || (isAsciiLetter(systemId[0]) && systemId[1] == T(':'))
  108. #endif
  109.      )
  110.     return systemId;
  111.   *toFree = (XML_Char *)malloc((tcslen(base) + tcslen(systemId) + 2)
  112.                                * sizeof(XML_Char));
  113.   if (!*toFree)
  114.     return systemId;
  115.   tcscpy(*toFree, base);
  116.   s = *toFree;
  117.   if (tcsrchr(s, T('/')))
  118.     s = tcsrchr(s, T('/')) + 1;
  119. #ifdef WIN32
  120.   if (tcsrchr(s, T('\\')))
  121.     s = tcsrchr(s, T('\\')) + 1;
  122. #endif
  123.   tcscpy(s, systemId);
  124.   return *toFree;
  125. }
  126.  
  127. static int
  128. externalEntityRefFilemap(XML_Parser parser,
  129.                          const XML_Char *context,
  130.                          const XML_Char *base,
  131.                          const XML_Char *systemId,
  132.                          const XML_Char *publicId)
  133. {
  134.   int result;
  135.   XML_Char *s;
  136.   const XML_Char *filename;
  137.   XML_Parser entParser = XML_ExternalEntityParserCreate(parser, context, 0);
  138.   PROCESS_ARGS args;
  139.   args.retPtr = &result;
  140.   args.parser = entParser;
  141.   filename = resolveSystemId(base, systemId, &s);
  142.   XML_SetBase(entParser, filename);
  143.   if (!filemap(filename, processFile, &args))
  144.     result = 0;
  145.   free(s);
  146.   XML_ParserFree(entParser);
  147.   return result;
  148. }
  149.  
  150. static int
  151. processStream(const XML_Char *filename, XML_Parser parser)
  152. {
  153.   /* passing NULL for filename means read intput from stdin */
  154.   int fd = 0;   /* 0 is the fileno for stdin */
  155.  
  156.   if (filename != NULL) {
  157.     fd = topen(filename, O_BINARY|O_RDONLY);
  158.     if (fd < 0) {
  159.       tperror(filename);
  160.       return 0;
  161.     }
  162.   }
  163.   for (;;) {
  164.     int nread;
  165.     char *buf = XML_GetBuffer(parser, READ_SIZE);
  166.     if (!buf) {
  167.       if (filename != NULL)
  168.         close(fd);
  169.       ftprintf(stderr, T("%s: out of memory\n"),
  170.                filename != NULL ? filename : "xmlwf");
  171.       return 0;
  172.     }
  173.     nread = read(fd, buf, READ_SIZE);
  174.     if (nread < 0) {
  175.       tperror(filename != NULL ? filename : "STDIN");
  176.       if (filename != NULL)
  177.         close(fd);
  178.       return 0;
  179.     }
  180.     if (XML_ParseBuffer(parser, nread, nread == 0) == XML_STATUS_ERROR) {
  181.       reportError(parser, filename != NULL ? filename : "STDIN");
  182.       if (filename != NULL)
  183.         close(fd);
  184.       return 0;
  185.     }
  186.     if (nread == 0) {
  187.       if (filename != NULL)
  188.         close(fd);
  189.       break;;
  190.     }
  191.   }
  192.   return 1;
  193. }
  194.  
  195. static int
  196. externalEntityRefStream(XML_Parser parser,
  197.                         const XML_Char *context,
  198.                         const XML_Char *base,
  199.                         const XML_Char *systemId,
  200.                         const XML_Char *publicId)
  201. {
  202.   XML_Char *s;
  203.   const XML_Char *filename;
  204.   int ret;
  205.   XML_Parser entParser = XML_ExternalEntityParserCreate(parser, context, 0);
  206.   filename = resolveSystemId(base, systemId, &s);
  207.   XML_SetBase(entParser, filename);
  208.   ret = processStream(filename, entParser);
  209.   free(s);
  210.   XML_ParserFree(entParser);
  211.   return ret;
  212. }
  213.  
  214. int
  215. XML_ProcessFile(XML_Parser parser,
  216.                 const XML_Char *filename,
  217.                 unsigned flags)
  218. {
  219.   int result;
  220.  
  221.   if (!XML_SetBase(parser, filename)) {
  222.     ftprintf(stderr, T("%s: out of memory"), filename);
  223.     exit(1);
  224.   }
  225.  
  226.   if (flags & XML_EXTERNAL_ENTITIES)
  227.       XML_SetExternalEntityRefHandler(parser,
  228.                                       (flags & XML_MAP_FILE)
  229.                                       ? externalEntityRefFilemap
  230.                                       : externalEntityRefStream);
  231.   if (flags & XML_MAP_FILE) {
  232.     PROCESS_ARGS args;
  233.     args.retPtr = &result;
  234.     args.parser = parser;
  235.     if (!filemap(filename, processFile, &args))
  236.       result = 0;
  237.   }
  238.   else
  239.     result = processStream(filename, parser);
  240.   return result;
  241. }
  242.